﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Autofac.Extensions.DependencyInjection;
using EasyNetQ;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using VOL.Core.Configuration;

using VOL.WebApi.Controllers.MqDataHandle;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
using VOL.Core.Extensions;
using NPOI.HSSF.UserModel;
using AutoMapper;
using VOL.Entity.DomainModels;
using VOL.Entity.VM;
using VOL.WebApi.Controllers.Hubs;
using System.Net.Sockets;
using System.Net;

namespace VOL.WebApi
{

public class MyMessage
    {
        public string Text { get; set; }
    }
    // 生产者类
    public class Producer
    {
        public void MQSendMsg(string message, string queue = "hello", string hostName = "192.168.110.183", int port = 5672, string userName = "admin", string password = "123456")
        {//http://192.168.110.183:15672/

            // 创建连接工厂对象
            var factory = new ConnectionFactory()
            {
                HostName = hostName, // 主机名
                Port =port, // 端口号
                UserName = userName, // 用户名
                Password = password// 密码
            };

            // 创建连接对象
            using (var connection = factory.CreateConnection())
            {
                // 创建通道对象
                using (var channel = connection.CreateModel())
                {
                    // 声明一个队列
                    channel.QueueDeclare(
                        queue: queue, // 队列名
                        durable: false, // 是否持久化
                        exclusive: false, // 是否排他
                        autoDelete: false, // 是否自动删除
                        arguments: null // 其他参数
                    );

                    // 定义要发送的消息内容
                    var body = Encoding.UTF8.GetBytes(message);

                    // 发送消息到队列
                    channel.BasicPublish(
                        exchange: "", // 交换机名，空字符串表示默认交换机
                        routingKey: queue, // 路由键，即队列名
                        basicProperties: null, // 消息属性，如持久化、优先级等
                        body: body // 消息体
                    );

                    Console.WriteLine(" [x] Sent {0}", message);
                }
            }

            Console.WriteLine(" Press [enter] to exit.");
      
        }
    }

    // 消费者类
    public class Consumer
    {
        public void MQReceived(string message, string queue = "hello",string hostName = "192.168.110.183", int port = 5672, string userName = "admin", string password = "123456")
        {
            // 创建连接工厂对象
            var factory = new ConnectionFactory()
            {
                HostName = hostName, // 主机名
                Port = port, // 端口号
                UserName = userName, // 用户名
                Password = password// 密码
            };

            // 创建连接对象
            using (var connection = factory.CreateConnection())
            {
                // 创建通道对象
                using (var channel = connection.CreateModel())
                {
                    // 声明一个队列，如果队列不存在则创建，如果存在则不影响
                    channel.QueueDeclare(
                        queue: queue, // 队列名
                        durable: false, // 是否持久化
                        exclusive: false, // 是否排他
                        autoDelete: false, // 是否自动删除
                        arguments: null // 其他参数
                    );

                    // 定义一个消费者对象，用于接收消息并处理
                    var consumer = new EventingBasicConsumer(channel);

                    consumer.Received += (model, ea) =>
                    {
                        var body = ea.Body.ToArray();
                        var message = Encoding.UTF8.GetString(body);
                        Console.WriteLine(" [x] Received {0}", message);
                    };

                    // 启动消费者，设置为手动应答模式（autoAck=false）
                    channel.BasicConsume(
                        queue: queue, // 队列名
                        autoAck: true, // 是否自动应答，false表示手动应答，需要调用BasicAck方法确认消息已处理完成，否则会导致消息堆积或重复消费；true表示自动应答，一旦接收到消息就认为已处理完成，无需确认。
                        consumer: consumer);  // 消费者对象

                    Console.WriteLine(" Press [enter] to exit.");
                   
                }
            }
        }
    }

    public class Program
    {
        
        public static  void Main(string[] args)
        {
            #region S7测试
            //S7.Net.Plc plc = new S7.Net.Plc(S7.Net.CpuType.S71200, "192.168.28.5", 0, 1);
            //plc.Open();
            #endregion

          

            AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
            AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
            //CreateHostBuilder(args).Build().Run();
            var host = CreateHostBuilder(args).Build();
            #region kafka¶©ÔÄÏûÏ¢
            //if (AppSetting.Kafka.UseConsumer)
            //{
            //    using var scope = host.Services.CreateScope();
            //    var testConsumer = scope.ServiceProvider.GetService<IKafkaConsumer<string, string>>();
            //    testConsumer.Consume(res =>
            //    {
            //        Console.WriteLine($"recieve:{DateTime.Now.ToLongTimeString()}  value:{res.Message.Value}");
            //        //¾²Ì¬·½·¨ Êý¾Ý´¦Àí Èë¿âµÈ²Ù×÷
            //        bool bl = DataHandle.AlarmData(res.Message.Value);
            //        //»Øµ÷º¯ÊýÐè·µ»Ø±ãÓÚÖ´ÐÐCommit
            //        return bl;
            //    }, AppSetting.Kafka.Topics.TestTopic);
            //}
            #endregion


            #region rbmq测试


            #endregion
            #region MQDemo
            //IConfigurationSection section = AppSetting.GetSection("MQ");
            //string hostName = section["HostName"];
            //string userName = section["UserName"];
            //string password = section["Password"];
            //int port = section["Port"].GetInt();
            //if (!string.IsNullOrEmpty(hostName))
            //{
            //    Producer producer = new Producer();
            //    producer.MQSendMsg("test", "gyg",hostName,port,userName,password);

            //    //Consumer consumer = new Consumer();
            //    //consumer.MQReceived("test", "gyg");
            //}
            #endregion

            #region socket
            MainSocket();
            //Thread socketThread = new Thread(new ThreadStart( MainSocket));
            //socketThread.IsBackground = true;
            //socketThread.Start();
            //Thread.Sleep(1000);
            //Console.WriteLine("Socket服务已启动");

            #endregion
            host.Run();
         
        }
        #region
        private static readonly int Port = 4000;
        private static TcpListener? server;
        private static bool isRunning = true;

        static async Task MainSocket()
        {
            try
            {
                server = new TcpListener(IPAddress.Any, Port);
                server.Start();
                Console.WriteLine($"服务器已启动，监听端口: {Port}");

                while (isRunning)
                {
                    Console.WriteLine("等待客户端连接...");
                    TcpClient client = await server.AcceptTcpClientAsync();
                    _ = HandleClientAsync(client);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"服务器错误: {ex.Message}");
            }
            finally
            {
                server?.Stop();
            }
        }

        private static async Task HandleClientAsync(TcpClient client)
        {
            string clientEndPoint = "未知客户端";
            try
            {
                if (client?.Client?.RemoteEndPoint != null)
                {
                    clientEndPoint = client.Client.RemoteEndPoint.ToString() ?? "未知客户端";
                }
                Console.WriteLine($"客户端已连接: {clientEndPoint}");

                using NetworkStream stream = client.GetStream();
                byte[] buffer = new byte[1024];

                while (client.Connected)
                {
                    int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
                    if (bytesRead == 0) break;

                    string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                    Console.WriteLine($"收到消息: {message}");

                    // 发送响应
                    string response = $"服务器已收到消息: {message}";
                    byte[] responseData = Encoding.UTF8.GetBytes(response);
                    await stream.WriteAsync(responseData, 0, responseData.Length);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"处理客户端时出错: {ex.Message}");
            }
            finally
            {
                try
                {
                    if (client?.Client != null)
                    {
                        client.Close();
                        Console.WriteLine($"客户端断开连接: {clientEndPoint}");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"关闭客户端连接时出错: {ex.Message}");
                }
            }
        }
        #endregion

        public static void MQReceived()
        {
            // 连接到 RabbitMQ 服务器
            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                // 声明一个队列
                channel.QueueDeclare(queue: "hello",
                                     durable: false,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);

                // 创建一个消费者
                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body.ToArray();
                    var message = Encoding.UTF8.GetString(body);
                    File.WriteAllText(@"C:\Users\Administrator\Desktop\333.txt", message, Encoding.UTF8);
                    Console.WriteLine(" [x] Received {0}", message);
                };
                channel.BasicConsume(queue: "hello",
                                     autoAck: true,
                                     consumer: consumer);
            }
        }
        public static void MQsend()
        {
            // 连接到 RabbitMQ 服务器
            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                // 声明一个队列
                channel.QueueDeclare(queue: "hello",
                                     durable: false,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);

                // 发送消息
                string message = "Hello World!";
                var body = Encoding.UTF8.GetBytes(message);
                channel.BasicPublish(exchange: "",
                                     routingKey: "hello",
                                     basicProperties: null,
                                     body: body);
                Console.WriteLine(" [x] Sent {0}", message);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public static void ReceiveMes()
        {
            //接收消息
            string queuqname = "firstQueue";
            ushort limitnum = 3;

            try
            {
                #region 构建消息队列
                //1.实例化连接工厂
                var factory = new RabbitMQ.Client.ConnectionFactory();
                factory.HostName = "localhost";
                factory.UserName = "guest";
                factory.Password = "guest";
                factory.AutomaticRecoveryEnabled = true;
                //2. 建立连接
                var connection = factory.CreateConnection();
                //3. 创建信道
                var channel = connection.CreateModel();

                var queue_name = queuqname;//项目下游上传的队列信息
                bool durable = true;//队列是否持久化
                bool exclusive = false;
                //设置 autoDeleted=true 的队列，当没有消费者之后，队列会自动被删除
                bool autoDelete = false;
                //4. 申明队列
                channel.QueueDeclare(queue_name, durable, exclusive, autoDelete, null);
                //5. 构造消费者实例
                var consumer = new RabbitMQ.Client.Events.EventingBasicConsumer(channel);
                bool autoAck = false;
                //autoAck:true；自动进行消息确认，当消费端接收到消息后，就自动发送ack信号，不管消息是否正确处理完毕
                //autoAck:false；关闭自动消息确认，通过调用BasicAck方法手动进行消息确认
                //6. 绑定消息接收后的事件委托

                //8. 启动消费者
                //设置prefetchCount : 3 来告知RabbitMQ，在未收到消费端的N条消息确认时，不再分发消息，也就确保了当消费端处于忙碌状态时
                channel.BasicQos(0, limitnum, false);

                channel.BasicConsume(queue_name, autoAck, consumer);

                #endregion

                #region 队列-接收消息的处理方法

                consumer.Received += (model, ea) =>
                {
                    try
                    {
                        //var body = ea.Body.ToArray();
                        var message = Encoding.UTF8.GetString(ea.Body.ToArray());
                        //获取消息后进行操作，do something
                        bool flag = false;
                        if (!string.IsNullOrEmpty(message))
                        {
                            try
                            {
                                //做其他存储或处理操作
                                //File.WriteAllText(@"C:\Users\Administrator\Desktop\333.txt", message, Encoding.UTF8);
                                Console.WriteLine("接收消息：" + message);
                                flag = true;


                            }
                            catch (Exception ex)
                            {
                            }
                        }
                        else
                        {
                            flag = true;
                        }
                        if (flag)
                        {
                            //操作完毕，则手动确认消息可删除
                            // 7. 发送消息确认信号（手动消息确认）
                            channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                        }
                    }
                    catch (Exception ex)
                    {
                    }
                };
                #endregion

            }
            catch (Exception ex)
            {

            }
        }
        /// <summary>
        /// RabbitMQ发送消息
        /// </summary>
        /// <param name="jsonstr">具体json格式的字符串</param>
        /// <param name="queuqname">具体入队的队列名称</param>
        /// <returns></returns>
        public static bool SendMsg(string jsonstr, string queuqname)
        {
            try
            {
                //1.实例化连接工厂
                var factory = new ConnectionFactory();
                factory.HostName = "localhost";
                factory.UserName = "guest";
                factory.Password = "guest";
                factory.AutomaticRecoveryEnabled = true;////设置端口后自动恢复连接属性
                //2. 建立连接
                var connection = factory.CreateConnection();
                //3. 创建信道
                var channel = connection.CreateModel();
                try
                {
                    var queue_name = queuqname;//具体入队的队列名称
                    bool durable = true;//队列是否持久化
                    bool exclusive = false;
                    //设置 autoDeleted=true 的队列，当没有消费者之后，队列会自动被删除
                    bool autoDelete = false;
                    //4. 申明队列
                    channel.QueueDeclare(queue_name, durable, exclusive, autoDelete, null);

                    //将消息标记为持久性 - 将IBasicProperties.SetPersistent设置为true
                    var properties = channel.CreateBasicProperties();
                    properties.Persistent = true; //持久化的消息

                    string message = jsonstr; //传递的消息内容
                    var body = Encoding.UTF8.GetBytes(message);

                    var exchange_name = "";
                    var routingKey = queue_name;//routingKey=queue_name，则为对应队列接收=queue_name

                    channel.BasicPublish(exchange_name, routingKey, properties, body); //开始传递(指定basicProperties)

                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("RabbitMQ 发送数据异常：" + ex.Message);
                    //PubTool.ConnError("RabbitMQ", "RunLog", "发送数据异常：" + ex.Message);
                }
                finally
                {
                    connection.Close();
                    channel.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("RabbitMQ 外层调用发送方法，发生异常：" + ex.Message);
                //PubTool.ConnError("RabbitMQ", "RunLog", "外层调用发送方法，发生异常：" + ex.Message);
            }
            return false;
        }
        static void Methed(object model, BasicDeliverEventArgs ea, IModel channel)
        {
            try
            {
                //var body = ea.Body.ToArray();
                var message = Encoding.UTF8.GetString(ea.Body.ToArray());
                //获取消息后进行操作，do something
                bool flag = false;
                if (!string.IsNullOrEmpty(message))
                {
                    try
                    {
                        //做其他存储或处理操作
                      //  File.WriteAllText(@"C:\Users\Administrator\Desktop\333.txt", message, Encoding.UTF8);
                        Console.WriteLine("ok :" + message);
                        flag = true;


                    }
                    catch (Exception ex)
                    {
                    }
                }
                else
                {
                    flag = true;
                }
                if (flag)
                {
                    //操作完毕，则手动确认消息可删除
                    // 7. 发送消息确认信号（手动消息确认）
                    channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                }
            }
            catch (Exception ex)
            {
            }
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
               Host.CreateDefaultBuilder(args)
                   .ConfigureWebHostDefaults(webBuilder =>
                   {
                       webBuilder.ConfigureKestrel(serverOptions =>
                       {
                           serverOptions.Limits.MaxRequestBodySize = 10485760;
                           // Set properties and call methods on options
                       });
                       webBuilder.UseKestrel().UseUrls("http://*:3000");//9991
                       webBuilder.UseIIS();
                       webBuilder.UseStartup<Startup>();
                   }).UseServiceProviderFactory(new AutofacServiceProviderFactory());
    }
}
